package com.the_last.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.the_last.constant.OrderConstant;
import com.the_last.constant.RedisKeyConstant;
import com.the_last.mapper.OrderMapper;
import com.the_last.pojo.po.Order;
import com.the_last.pojo.po.OrderTable;
import com.the_last.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 订单超时处理服务
 * 
 * @author zhanghaifeng
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderTimeoutService {
    
    private final OrderMapper orderMapper;
    private final RedisUtil redisUtil;
    private final OrderTableService orderTableService;
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 处理订单超时逻辑
     * @param orderId 订单ID
     * @param messageId 消息唯一标识（用于防重复消费）
     * @return 是否处理成功
     */
    public boolean processOrderTimeout(Long orderId, String messageId) {
        String currentTime = LocalDateTime.now().format(FORMATTER);
        log.info("[{}] 开始处理订单超时，订单ID: {}, 消息ID: {}", currentTime, orderId, messageId);
        
        try {
            // 检查Redis中是否已处理过该消息，防止重复消费
            String redisKey = OrderConstant.ORDER_TIMEOUT_MESSAGE_KEY_PREFIX + messageId;
            if (Boolean.TRUE.equals(redisUtil.get(redisKey) != null)) {
                log.warn("消息已处理过，跳过重复消费，消息ID: {}", messageId);
                return true;
            }
            
            // 查询订单信息
            Order order = orderMapper.selectById(orderId);
            if (order == null) {
                log.warn("订单不存在，订单ID: {}", orderId);
                // 设置处理标识，避免重复处理
                redisUtil.set(redisKey, "processed", OrderConstant.ORDER_MESSAGE_EXPIRE_SECONDS);
                return false;
            }
            
            log.info("查询到订单信息，订单状态: {}, 创建时间: {}", order.getStatus(), order.getSubmitTime());
            
            // 检查订单状态，只有未支付的订单才需要超时处理
            if (!Order.STATUS_NOT_PAID.equals(order.getStatus())) {
                log.info("订单状态不是未支付状态，无需超时处理，当前状态: {}", order.getStatus());
                // 设置处理标识
                redisUtil.set(redisKey, "processed", OrderConstant.ORDER_MESSAGE_EXPIRE_SECONDS);
                return true;
            }
            
            // 更新订单状态为超时关闭
            order.setStatus(Order.STATUS_TIMEOUT_CLOSED);
            
            int updateCount = orderMapper.updateById(order);
            if (updateCount > 0) {
                log.info("订单超时处理成功，订单ID: {} 已设置为超时关闭状态", orderId);
                
                // 返还库存和减少销量
                restoreStockAndSales(orderId);
                
                // 设置处理标识
                redisUtil.set(redisKey, "processed", OrderConstant.ORDER_MESSAGE_EXPIRE_SECONDS);
                return true;
            } else {
                log.error("更新订单状态失败，订单ID: {}", orderId);
                return false;
            }
            
        } catch (Exception e) {
            log.error("处理订单超时失败，订单ID: {}, 消息ID: {}", orderId, messageId, e);
            return false;
        }
    }
    
    /**
     * 返还库存和减少销量
     * 参考 OrderServiceImpl#submitOrder 的批量处理方式，减少Redis请求次数
     * 
     * @param orderId 订单ID
     */
    private void restoreStockAndSales(Long orderId) {
        try {
            // 1. 查询订单商品明细
            QueryWrapper<OrderTable> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("order_id", orderId);
            List<OrderTable> orderTables = orderTableService.list(queryWrapper);
            
            if (orderTables == null || orderTables.isEmpty()) {
                log.warn("订单无商品明细，无需返还库存和销量，订单ID: {}", orderId);
                return;
            }
            
            // 2. 提取所有需要返还的商品ID
            Set<String> productIds = orderTables.stream()
                    .map(orderTable -> String.valueOf(orderTable.getProductId()))
                    .collect(Collectors.toSet());
            
            // 3. 一次性批量获取当前库存和销量信息
            Map<String, String> stockMap = redisUtil.hMGet(RedisKeyConstant.PRODUCT_STOCK_KEY, productIds);
            Map<String, String> salesMap = redisUtil.hMGet(RedisKeyConstant.PRODUCT_SALES_KEY, productIds);
            
            // 4. 在内存中计算返还后的库存和销量
            Map<String, String> newStockMap = new HashMap<>(stockMap.size());
            Map<String, String> newSalesMap = new HashMap<>(salesMap.size());
            
            for (OrderTable orderTable : orderTables) {
                String productId = String.valueOf(orderTable.getProductId());
                Integer quantity = orderTable.getQuantity();
                
                // 返还库存：当前库存 + 购买数量
                String currentStockStr = stockMap.get(productId);
                if (currentStockStr != null) {
                    int currentStock = Integer.parseInt(currentStockStr);
                    int newStock = currentStock + quantity;
                    newStockMap.put(productId, String.valueOf(newStock));
                    log.debug("商品ID: {}, 返还库存: {} → {}", productId, currentStock, newStock);
                } else {
                    log.warn("商品ID: {} 的库存信息不存在，跳过库存返还", productId);
                }
                
                // 减少销量：当前销量 - 购买数量
                String currentSalesStr = salesMap.get(productId);
                if (currentSalesStr != null) {
                    int currentSales = Integer.parseInt(currentSalesStr);
                    int newSales = Math.max(0, currentSales - quantity); // 确保销量不为负数
                    newSalesMap.put(productId, String.valueOf(newSales));
                    log.debug("商品ID: {}, 减少销量: {} → {}", productId, currentSales, newSales);
                } else {
                    log.warn("商品ID: {} 的销量信息不存在，跳过销量减少", productId);
                }
            }
            
            // 5. 一次性批量更新库存和销量
            if (!newStockMap.isEmpty()) {
                redisUtil.hMSet(RedisKeyConstant.PRODUCT_STOCK_KEY, newStockMap);
                log.info("批量更新库存成功，订单ID: {}, 涉及商品数量: {}", orderId, newStockMap.size());
            }
            
            if (!newSalesMap.isEmpty()) {
                redisUtil.hMSet(RedisKeyConstant.PRODUCT_SALES_KEY, newSalesMap);
                log.info("批量更新销量成功，订单ID: {}, 涉及商品数量: {}", orderId, newSalesMap.size());
            }
            
            log.info("库存和销量返还完成，订单ID: {}", orderId);
            
        } catch (Exception e) {
            log.error("返还库存和销量失败，订单ID: {}", orderId, e);
        }
    }
}